﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CommonBehaviors.Actions;
using Styx;
using Styx.Logic;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
using TreeSharp;
using Action = TreeSharp.Action;

namespace Altarboy
{

    class DisciplinePriest
    {
        #region Delegates
        public delegate bool SimpleBoolReturnDelegate(object context);
        public delegate WoWUnit UnitSelectionDelegate(object context);
        #endregion


        // Current Player   
        public static LocalPlayer Me { get { return StyxWoW.Me; } }

      
       
         public static Composite Combat()
        {
          
            return new PrioritySelector(
              
               Heal(),
               
               //Combat - If nothing else to do.
               new Decorator(ret => (!AltarboyCore.IsHealer || Me.ManaPercent >= 50),
                   new Sequence(
                        Target(), //Select a target
                        SingleTargetDps()//Then kill it. (No AOE Here Really)
                    ) 
                )
            );

        }

         #region Healing

         public static WoWPlayer HealTarget;
         public static Composite Heal()
         {
             return new Sequence(
                 TargetForHealing(),  //Find the best target to heal.
                 HealPlayer()  //Then Heal it.
             );
         }

        public static Composite TargetForHealing()
        {
            return new PrioritySelector(
                // There should be different logic for solo/party/raiding for healing target selection.
               
                //Solo mode...
                new Decorator(ret=> !Me.IsInParty && !Me.IsInRaid && Me.HealthPercent  <= 99,
                    new Action(delegate{
                        HealTarget = Me;
                        return RunStatus.Success;
                    })
                ),

                //In a party as heals
               new Decorator(ret => (Me.IsInParty || Me.IsInRaid) && PartyManager.NearbyGroupMembers.Any(p => p.HealthPercent <= 80),
                    new Action(delegate
                    {
                        HealTarget = PartyManager.NearbyGroupMembers.Where(p => HealScore(p) <= 80).OrderBy(p => HealScore(p)).FirstOrDefault();
                        return RunStatus.Success;
                    })
                ),

               new Action(delegate
                {
                    HealTarget = null;
                    return RunStatus.Failure;
                })

            );
        }
        
         public static Composite HealPlayer()
         {
            return new Decorator(ret => HealTarget != null,
              new PrioritySelector(

               //new Decorator(ret => TargetManager.ActiveTarget != HealTarget,
               //     new Action(delegate { TargetManager.SetTarget(HealTarget, TargetManager.TargetMode.HealPlayer); })
               //),
              
               new Decorator(
                   ret => PriestComposites.CanPowerWordShield(HealTarget) && HealTarget.HealthPercent <= 90,
                   AltarboyComposites.CastSpell("Power Word: Shield", ret => (true), HealTarget)
               ),
               new Decorator(
                   ret => AuraManager.GetAuraTimeLeft("Renew", HealTarget, true).TotalSeconds <= 1 && HealTarget.HealthPercent <= AltarboySettings.Instance.DiscRenewPercent ,
                   AltarboyComposites.CastSpell("Renew", ret => (true), HealTarget)
               ),
               new Decorator(ret => HealTarget.HealthPercent <= 40, AltarboyComposites.CastSpell("Penance", ret => (true), HealTarget)),
               new Decorator(ret => HealTarget.HealthPercent <= 30, AltarboyComposites.CastSpell("Flash Heal", ret => (true), HealTarget)),
               new Decorator(ret => HealTarget.HealthPercent <= 60, AltarboyComposites.CastSpell("Heal", ret => (true), HealTarget)),
             
              
               new Action(delegate { return RunStatus.Failure; })
            ));
          
         }

        #endregion Healing

         #region Combat

        public static Composite Target()
        {
            return new PrioritySelector(
                 new Decorator(ret => AltarboySettings.Instance.EnableTargeting,
                    new Sequence(
                      
                        //cache possible targets
                       new Action(delegate{
                            TargetManager.AcquireTargets();
                        }),

                        new PrioritySelector(
                            TargetManager.SelectMultiDotTarget(),
                            TargetManager.SelectClosestTarget()

                        ),
                        
                        //reset target cache
                        new Action(delegate{
                            TargetManager.ResetTargets();
                        })
                 )
               )
            );
        }

        public static Composite Pull()
        {
            return new PrioritySelector(
               AltarboyComposites.CreateMoveToAndFace(100, 180, ret => TargetManager.ActiveTarget, false),
                AltarboyComposites.CastSpell("Shadow Word: Pain", ret => (true), TargetManager.ActiveTarget)
             );
        }
       
        private static Composite SingleTargetDps()
        {
            //Never Attack Anything That we shouldnt
            return new Decorator(
                ret => TargetManager.ShouldAttack(TargetManager.ActiveTarget),
                     new PrioritySelector(
                       new Decorator(ret => Me.IsMoving, MovementDps()),
                       new Decorator(ret => !Me.IsMoving, StationaryDps())
                      )
                );
        }

        private static Composite StationaryDps()
        {
            return new Sequence(

               //this is the stationary composite, so it shouldn't be an issue to face the target.
               new TreeSharp.Action(delegate { if (!Me.IsMoving) { TargetManager.ActiveTarget.Face(); } }),

              new PrioritySelector(
                 //  AltarboyComposites.WaitForCastToFinish(),
                    AltarboyComposites.CastSpell("Shadow Word: Pain", ret => (AuraManager.GetAuraTimeLeft("Shadow Word: Pain", TargetManager.ActiveTarget, true).TotalSeconds <= .4), TargetManager.ActiveTarget),
                   AltarboyComposites.CastSpell("Penance", ret => (true), TargetManager.ActiveTarget),
                    AltarboyComposites.CastSpell("Holy Fire", ret => (true), TargetManager.ActiveTarget),
                   AltarboyComposites.CastSpell("Mind Blast", ret => (true), TargetManager.ActiveTarget),
                   AltarboyComposites.CastSpell("Smite", ret => (true), TargetManager.ActiveTarget)
                 //  AltarboyComposites.CreateUseWand()
                  // new Action(ret => Me.ToggleAttack())
             )
         );
        }

        private static Composite MovementDps()
        {
            return new PrioritySelector(

                AltarboyComposites.CastSpell("Shadow Word: Pain", ret => (
                    AuraManager.GetAuraTimeLeft("Shadow Word: Pain", TargetManager.ActiveTarget, true).TotalSeconds <= .4)
                , TargetManager.ActiveTarget)

            );
        }

        #endregion

        #region Conditionals
        private static Boolean TargetNeedsMultiDot(WoWUnit target)
        {
            return target.Distance2D <= 40 &&
                target.InLineOfSight &&
                AuraManager.GetAuraTimeLeft("Shadow Word: Pain", target, true).TotalSeconds < 1.5;
        }

        public static double HealScore(WoWUnit target)
        {
            if(target != null)
            {
              
                return target.HealthPercent;
            }

            return 0;
        }

        #endregion
    }
}
